/**
 * Copyright &copy; 2012-2013 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.gosling.cloudspace.tools;

import com.gosling.cloudspace.common.constants.CommonConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import static java.math.BigDecimal.ROUND_HALF_UP;

/**
 * 文件操作工具类
 * 实现文件的创建、删除、复制、压缩、解压以及目录的创建、删除、复制、压缩解压等功能
 *
 * @author lihonglin
 * @date 2022/3/21 15:39
 */
public class FileTool {

    // 字符串截取范围单位,这里是1MB。
    private static final int RANGE_UNIT = 1024;
    private static final int B_1024 = 1024;
    private static final int KB_1048576 = 1048576;
    private static final int MB_1073741824 = 1073741824;
    private static final int GB_1048576 = 1048576;
    private static Logger log = LoggerFactory.getLogger(FileTool.class);

    /**
     * 复制单个文件，如果目标文件存在，则不覆盖
     *
     * @param srcFileName  待复制的文件名
     * @param descFileName 目标文件名
     * @return 如果复制成功，则返回true，否则返回false
     */
    public static boolean copyFile(String srcFileName, String descFileName) {
        return FileTool.copyFileCover(srcFileName, descFileName, false);
    }

    /***
     * 判断是否是图片类型
     *
     * @param file
     * @return
     */
    public static boolean isPngOrJpegOrJpg(MultipartFile file) {
        InputStream is = null;
        boolean result = false;
        try {
            //转换为input,为了使流能够实现markSupported
            is = new BufferedInputStream(file.getInputStream());
            //使用poi中的类判断
            FileMagic fileMagic = FileMagic.valueOf(is);
            if (CommonConstants.IMAGE_FILE_MAGIC.contains(fileMagic)) {
                result = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(is);
        }
        return result;
    }

    /**
     * 复制单个文件
     *
     * @param srcFileName  待复制的文件名
     * @param descFileName 目标文件名
     * @param coverlay     如果目标文件已存在，是否覆盖
     * @return 如果复制成功，则返回true，否则返回false
     */
    public static boolean copyFileCover(String srcFileName, String descFileName, boolean coverlay) {
        File srcFile = new File(srcFileName);
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            log.debug("复制文件失败，源文件" + srcFileName + "不存在!");
            return false;
        }
        // 判断源文件是否是合法的文件
        else if (!srcFile.isFile()) {
            log.debug("复制文件失败，" + srcFileName + "不是一个文件!");
            return false;
        }
        File descFile = new File(descFileName);
        // 判断目标文件是否存在
        if (descFile.exists()) {
            // 如果目标文件存在，并且允许覆盖
            if (coverlay) {
                log.debug("目标文件已存在，准备删除!");
                if (!FileTool.delFile(descFileName)) {
                    log.debug("删除目标文件" + descFileName + "失败!");
                    return false;
                }
            } else {
                log.debug("复制文件失败，目标文件" + descFileName + "已存在!");
                return false;
            }
        } else {
            if (!descFile.getParentFile().exists()) {
                // 如果目标文件所在的目录不存在，则创建目录
                log.debug("目标文件所在的目录不存在，创建目录!");
                // 创建目标文件所在的目录
                if (!descFile.getParentFile().mkdirs()) {
                    log.debug("创建目标文件所在的目录失败!");
                    return false;
                }
            }
        }

        // 准备复制文件
        // 读取的位数
        int readByte = 0;
        InputStream ins = null;
        OutputStream outs = null;
        try {
            // 打开源文件
            ins = new FileInputStream(srcFile);
            // 打开目标文件的输出流
            outs = new FileOutputStream(descFile);
            byte[] buf = new byte[1024];
            // 一次读取1024个字节，当readByte为-1时表示文件已经读取完毕
            while ((readByte = ins.read(buf)) != -1) {
                // 将读取的字节流写入到输出流
                outs.write(buf, 0, readByte);
            }
            log.debug("复制单个文件" + srcFileName + "到" + descFileName
                    + "成功!");
            return true;
        } catch (Exception e) {
            log.debug("复制文件失败：" + e.getMessage());
            return false;
        } finally {
            // 关闭输入输出流，首先关闭输出流，然后再关闭输入流
            IOTool.closeQuietly(outs);
            IOUtils.closeQuietly(ins);
        }
    }

    public static StringBuilder readFile2String2(File file) {
        StringBuilder sb = new StringBuilder((int) (file.length() / 3 * 4));
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(file);
            int bSize = 3 * 1024;
            byte[] buf = new byte[bSize];
            int len = 0;
            while ((len = fin.read(buf)) != -1) {
                byte[] encoded = Base64.encodeBase64(buf);
                sb.append(new String(buf, 0, len));
            }
        } catch (IOException e) {
            IOTool.closeQuietly(fin);
        }
        return sb;
    }

    /***
     * 读取文件内容
     * @param file
     * @return
     */
    public static String readFile2StringByte(File file) {
        ByteArrayOutputStream os1 = null;
        InputStream file1 = null;
        try {
            os1 = new ByteArrayOutputStream();
            file1 = new FileInputStream(file);
            byte[] byteBuf = new byte[3 * 1024 * 1024];
            byte[] base64ByteBuf;
            //每次从文件中读取到的有效字节数
            int count1;
            while ((count1 = file1.read(byteBuf)) != -1) {
                //如果有效字节数不为3*1000，则说明文件已经读到尾了，不够填充满byteBuf了
                if (count1 != byteBuf.length) {
                    //从byteBuf中截取包含有效字节数的字节段
                    byte[] copy = Arrays.copyOf(byteBuf, count1);
                    //对有效字节段进行编码
                    base64ByteBuf = Base64.encodeBase64(copy);
                } else {
                    base64ByteBuf = Base64.encodeBase64(byteBuf);
                }
                os1.write(base64ByteBuf, 0, base64ByteBuf.length);
                os1.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(file1);
            IOTool.closeQuietly(os1);
        }
        return os1.toString();
    }

    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        StringBuilder prestr = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {
                prestr.append(key).append("=").append(value);
            } else {
                prestr.append(key).append("=").append(value).append("&");
            }
        }
        return prestr.toString();
    }

    /**
     * 复制整个目录的内容，如果目标目录存在，则不覆盖
     *
     * @param srcDirName  源目录名
     * @param descDirName 目标目录名
     * @return 如果复制成功返回true，否则返回false
     */
    public static boolean copyDirectory(String srcDirName, String descDirName) {
        return FileTool.copyDirectoryCover(srcDirName, descDirName,
                false);
    }

    /**
     * 复制整个目录的内容
     *
     * @param srcDirName  源目录名
     * @param descDirName 目标目录名
     * @param coverlay    如果目标目录存在，是否覆盖
     * @return 如果复制成功返回true，否则返回false
     */
    public static boolean copyDirectoryCover(String srcDirName,
                                             String descDirName, boolean coverlay) {
        File srcDir = new File(srcDirName);
        // 判断源目录是否存在
        if (!srcDir.exists()) {
            log.debug("复制目录失败，源目录" + srcDirName + "不存在!");
            return false;
        }
        // 判断源目录是否是目录
        else if (!srcDir.isDirectory()) {
            log.debug("复制目录失败，" + srcDirName + "不是一个目录!");
            return false;
        }
        // 如果目标文件夹名不以文件分隔符结尾，自动添加文件分隔符
        String descDirNames = descDirName;
        if (!descDirNames.endsWith(File.separator)) {
            descDirNames = descDirNames + File.separator;
        }
        File descDir = new File(descDirNames);
        // 如果目标文件夹存在
        if (descDir.exists()) {
            if (coverlay) {
                // 允许覆盖目标目录
                log.debug("目标目录已存在，准备删除!");
                if (!FileTool.delFile(descDirNames)) {
                    log.debug("删除目录" + descDirNames + "失败!");
                    return false;
                }
            } else {
                log.debug("目标目录复制失败，目标目录" + descDirNames + "已存在!");
                return false;
            }
        } else {
            // 创建目标目录
            log.debug("目标目录不存在，准备创建!");
            if (!descDir.mkdirs()) {
                log.debug("创建目标目录失败!");
                return false;
            }

        }

        boolean flag = true;
        // 列出源目录下的所有文件名和子目录名
        File[] files = srcDir.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 如果是一个单个文件，则直接复制
            if (files[i].isFile()) {
                flag = FileTool.copyFile(files[i].getAbsolutePath(),
                        descDirName + files[i].getName());
                // 如果拷贝文件失败，则退出循环
                if (!flag) {
                    break;
                }
            }
            // 如果是子目录，则继续复制目录
            if (files[i].isDirectory()) {
                flag = FileTool.copyDirectory(files[i]
                        .getAbsolutePath(), descDirName + files[i].getName());
                // 如果拷贝目录失败，则退出循环
                if (!flag) {
                    break;
                }
            }
        }

        if (!flag) {
            log.debug("复制目录" + srcDirName + "到" + descDirName + "失败!");
            return false;
        }
        log.debug("复制目录" + srcDirName + "到" + descDirName + "成功!");
        return true;

    }

    /**
     * 删除文件，可以删除单个文件或文件夹
     *
     * @param fileName 被删除的文件名
     * @return 如果删除成功，则返回true，否是返回false
     */
    public static boolean delFile(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            log.debug(fileName + "文件不存在!");
            return true;
        } else {
            if (file.isFile()) {
                return FileTool.deleteFile(fileName);
            } else {
                return FileTool.deleteDirectory(fileName);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 被删除的文件名
     * @return 如果删除成功，则返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                log.info("删除单个文件" + fileName + "成功!");
                return true;
            } else {
                log.info("删除单个文件" + fileName + "失败!");
                return false;
            }
        } else {
            log.info(fileName + "文件不存在!");
            return true;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dirName 被删除的目录所在的文件路径
     * @return 如果目录删除成功，则返回true，否则返回false
     */
    public static boolean deleteDirectory(String dirName) {
        String dirNames = dirName;
        if (!dirNames.endsWith(File.separator)) {
            dirNames = dirNames + File.separator;
        }
        File dirFile = new File(dirNames);
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            log.debug(dirNames + "目录不存在!");
            return true;
        }
        boolean flag = true;
        // 列出全部文件及子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = FileTool.deleteFile(files[i].getAbsolutePath());
                // 如果删除文件失败，则退出循环
                if (!flag) {
                    break;
                }
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = FileTool.deleteDirectory(files[i]
                        .getAbsolutePath());
                // 如果删除子目录失败，则退出循环
                if (!flag) {
                    break;
                }
            }
        }

        if (!flag) {
            log.debug("删除目录失败!");
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            log.debug("删除目录" + dirName + "成功!");
            return true;
        } else {
            log.debug("删除目录" + dirName + "失败!");
            return false;
        }

    }

    /**
     * 创建单个文件
     *
     * @param descFileName 文件名，包含路径
     * @return 如果创建成功，则返回true，否则返回false
     */
    public static boolean createFile(String descFileName) {
        File file = new File(descFileName);
        if (file.exists()) {
            log.debug("文件" + descFileName + "已存在!");
            return false;
        }
        if (descFileName.endsWith(File.separator)) {
            log.debug(descFileName + "为目录，不能创建目录!");
            return false;
        }
        if (!file.getParentFile().exists()) {
            // 如果文件所在的目录不存在，则创建目录
            if (!file.getParentFile().mkdirs()) {
                log.debug("创建文件所在的目录失败!");
                return false;
            }
        }

        // 创建文件
        try {
            if (file.createNewFile()) {
                log.debug(descFileName + "文件创建成功!");
                return true;
            } else {
                log.debug(descFileName + "文件创建失败!");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.debug(descFileName + "文件创建失败!");
            return false;
        }

    }

    /**
     * 创建目录
     *
     * @param descDirName 目录名,包含路径
     * @return 如果创建成功，则返回true，否则返回false
     */
    public static boolean createDirectory(String descDirName) {
        String descDirNames = descDirName;
        if (!descDirNames.endsWith(File.separator)) {
            descDirNames = descDirNames + File.separator;
        }
        File descDir = new File(descDirNames);
        if (descDir.exists()) {
            log.debug("目录" + descDirNames + "已存在!");
            return false;
        }
        // 创建目录
        if (descDir.mkdirs()) {
            log.debug("目录" + descDirNames + "创建成功!");
            return true;
        } else {
            log.debug("目录" + descDirNames + "创建失败!");
            return false;
        }

    }

    /**
     * 压缩文件或目录
     *
     * @param srcDirName   压缩的根目录
     * @param fileName     根目录下的待压缩的文件名或文件夹名，其中*或""表示跟目录下的全部文件
     * @param descFileName 目标zip文件
     */
    public static void zipFiles(String srcDirName, String fileName,
                                String descFileName) {
        // 判断目录是否存在
        if (srcDirName == null) {
            log.debug("文件压缩失败，目录" + srcDirName + "不存在!");
            return;
        }
        File fileDir = new File(srcDirName);
        if (!fileDir.exists() || !fileDir.isDirectory()) {
            log.debug("文件压缩失败，目录" + srcDirName + "不存在!");
            return;
        }
        String dirPath = fileDir.getAbsolutePath();
        File descFile = new File(descFileName);
        try {
            ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(descFile));
            if ("*".equals(fileName) || "".equals(fileName)) {
                FileTool.zipDirectoryToZipFile(dirPath, fileDir, zouts);
            } else {
                File file = new File(fileDir, fileName);
                if (file.isFile()) {
                    FileTool.zipFilesToZipFile(dirPath, file, zouts);
                } else {
                    FileTool.zipDirectoryToZipFile(dirPath, file, zouts);
                }
            }
            zouts.close();
            log.debug(descFileName + "文件压缩成功!");
        } catch (Exception e) {
            log.debug("文件压缩失败：" + e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     * 解压缩ZIP文件，将ZIP文件里的内容解压到descFileName目录下
     *
     * @param zipFileName  需要解压的ZIP文件
     * @param descFileName 目标文件
     */
    public static boolean unZipFiles(String zipFileName, String descFileName) {
        String descFileNames = descFileName;
        OutputStream os = null;
        InputStream is = null;
        if (!descFileNames.endsWith(File.separator)) {
            descFileNames = descFileNames + File.separator;
        }
        try {
            // 根据ZIP文件创建ZipFile对象
            ZipFile zipFile = new ZipFile(zipFileName);
            ZipEntry entry = null;
            String entryName = null;
            String descFileDir = null;
            byte[] buf = new byte[4096];
            int readByte = 0;
            // 获取ZIP文件里所有的entry
            @SuppressWarnings("rawtypes")
            Enumeration enums = zipFile.entries();
            // 遍历所有entry
            while (enums.hasMoreElements()) {
                entry = (ZipEntry) enums.nextElement();
                // 获得entry的名字
                entryName = entry.getName();
                descFileDir = descFileNames + entryName;
                if (entry.isDirectory()) {
                    // 如果entry是一个目录，则创建目录
                    new File(descFileDir).mkdirs();
                    continue;
                } else {
                    // 如果entry是一个文件，则创建父目录
                    new File(descFileDir).getParentFile().mkdirs();
                }
                File file = new File(descFileDir);
                // 打开文件输出流
                os = new FileOutputStream(file);
                // 从ZipFile对象中打开entry的输入流
                is = zipFile.getInputStream(entry);
                while ((readByte = is.read(buf)) != -1) {
                    os.write(buf, 0, readByte);
                }
                os.close();
                is.close();
            }
            zipFile.close();
            log.debug("文件解压成功!");
            return true;
        } catch (Exception e) {
            log.debug("文件解压失败：" + e.getMessage());
            return false;
        } finally {
            IOTool.closeQuietly(os);
            IOUtils.closeQuietly(is);
        }
    }

    /**
     * 将目录压缩到ZIP输出流
     *
     * @param dirPath 目录路径
     * @param fileDir 文件信息
     * @param zouts   输出流
     */
    public static void zipDirectoryToZipFile(String dirPath, File fileDir, ZipOutputStream zouts) {
        if (fileDir.isDirectory()) {
            File[] files = fileDir.listFiles();
            // 空的文件夹
            if (files.length == 0) {
                // 目录信息
                ZipEntry entry = new ZipEntry(getEntryName(dirPath, fileDir));
                try {
                    zouts.putNextEntry(entry);
                    zouts.closeEntry();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return;
            }

            for (File file : files) {
                if (file.isFile()) {
                    // 如果是文件，则调用文件压缩方法
                    FileTool.zipFilesToZipFile(dirPath, file, zouts);
                } else {
                    // 如果是目录，则递归调用
                    FileTool.zipDirectoryToZipFile(dirPath, file, zouts);
                }
            }
        }
    }

    public static void createExcel(String fileName) {

        // 获取文件的格式
        //D:\home\maxwell\generateMerchantNo\164697副本.zip
        String fileFormat;
        try {
            fileFormat = fileName.substring(fileName.lastIndexOf(".") + 1);
            fileName = fileName.substring(0, fileName.lastIndexOf("."));
        } catch (StringIndexOutOfBoundsException e) {
            System.out.println(1111);
        }

    }

    public static void main(String[] args) {
        // 获取文件的格式
        //D:\home\maxwell\generateMerchantNo\164697副本.zip
        File file = new File("D:\\home\\maxwell\\generateMerchantNo\\16469861674979202202204011220150307.zip");
        String fileName = file.getName();
        String fileFormat = "";
        try {
            fileFormat = fileName.substring(fileName.lastIndexOf(".") + 1);
            fileName = fileName.substring(0, fileName.lastIndexOf("."));
        } catch (StringIndexOutOfBoundsException e) {
            System.out.println(1111);
        }
        System.out.println(fileFormat);
        System.out.println(fileName);
    }

    /**
     * 将文件压缩到ZIP输出流
     *
     * @param dirPath 目录路径
     * @param file    文件
     * @param zouts   输出流
     */
    public static void zipFilesToZipFile(String dirPath, File file, ZipOutputStream zouts) {
        FileInputStream fin = null;
        ZipEntry entry = null;
        // 创建复制缓冲区
        byte[] buf = new byte[4096];
        int readByte = 0;
        if (file.isFile()) {
            try {
                // 创建一个文件输入流
                fin = new FileInputStream(file);
                // 创建一个ZipEntry
                entry = new ZipEntry(getEntryName(dirPath, file));
                // 存储信息到压缩文件
                zouts.putNextEntry(entry);
                // 复制字节到压缩文件
                while ((readByte = fin.read(buf)) != -1) {
                    zouts.write(buf, 0, readByte);
                }
                zouts.closeEntry();
                System.out.println("添加文件" + file.getAbsolutePath() + "到zip文件中!");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOTool.closeQuietly(fin);
            }
        }
    }

    /**
     * 获取待压缩文件在ZIP文件中entry的名字，即相对于跟目录的相对路径名
     *
     * @param dirPath 目录名
     * @param file    entry文件名
     * @return
     */
    private static String getEntryName(String dirPath, File file) {
        String dirPaths = dirPath;
        if (!dirPaths.endsWith(File.separator)) {
            dirPaths = dirPaths + File.separator;
        }
        String filePath = file.getAbsolutePath();
        // 对于目录，必须在entry名字后面加上"/"，表示它将以目录项存储
        if (file.isDirectory()) {
            filePath += "/";
        }
        int index = filePath.indexOf(dirPaths);
        return filePath.substring(index + dirPaths.length());
    }

    /**
     * 将内容写入文件
     *
     * @param content
     * @param filePath
     */
    public static void writeFile(String content, String filePath) {
        try {
            if (FileTool.createFile(filePath)) {
                Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), StandardCharsets.UTF_8));
                writer.write(content);
                writer.close();
            } else {
                if (deleteFile(filePath)) {
                    writeFile(content, filePath);
                    log.info("文件重新生成！");
                }
            }
        } catch (Exception e) {
            log.error("写入文件错误！", e);
        }
    }

    /***
     * 检验文件是否存在
     *
     * @param filePath
     * @return
     */
    public static boolean checkFileExists(String filePath) {
        File file = new File(filePath);
        if (file.exists() && file.length() > 0) {
            String md5 = MD5Tool.getMd5ByFile(file);
            if (StringUtils.isNotEmpty(md5)) {
                log.info("文件保存成功！");
                return true;
            }
        }
        log.error("文件保存失败！");
        return false;
    }

    /**
     * 返回文件大小
     * 描述:
     *
     * @author: name
     */
    public static String getFileSize(File file) {
        String size = "";
        if (file.exists() && file.isFile()) {
            long fileS = file.length();
            DecimalFormat df = new DecimalFormat("#.00");
            if (fileS < B_1024) {
                size = df.format((double) fileS) + "B";
            } else if (fileS < KB_1048576) {
                size = df.format((double) fileS / B_1024) + "KB";
            } else if (fileS < MB_1073741824) {
                size = df.format((double) fileS / KB_1048576) + "MB";
            } else {
                size = df.format((double) fileS / MB_1073741824) + "GB";
            }
        } else if (file.exists() && file.isDirectory()) {
            size = "";
        } else {
            size = "0B";
        }
        return size;
    }

    /**
     * 转换文件大小的方法
     *
     * @author lihonglin
     * @date 2022/3/21 15:45
     */
    public static String getFileSize(long size) {
        if (size < 1024) {
            return size + "B";
        } else if (size < KB_1048576) {
            double beforeNum = size / B_1024;
            double temp = size % B_1024;
            double afterNum = temp / B_1024;
            // 取小数点后1位
            double num = new BigDecimal(beforeNum + afterNum).setScale(1, ROUND_HALF_UP).doubleValue();
            return num + "KB";
        } else if (size < MB_1073741824) {
            double beforeNum = size / KB_1048576;
            double temp = size % KB_1048576;
            double afterNum = temp / KB_1048576;
            double num = new BigDecimal(beforeNum + afterNum).setScale(2, ROUND_HALF_UP).doubleValue();
            return num + "MB";
        } else {
            double beforeNum = size / MB_1073741824;
            double temp = size % MB_1073741824;
            double afterNum = temp / MB_1073741824;
            double num = new BigDecimal(beforeNum + afterNum).setScale(2, ROUND_HALF_UP).doubleValue();
            return num + "GB";
        }
    }

}

